package javax.slee.management;

/**
 * This class identifies a notification such as an {@link AlarmNotification alarm} or
 * {@link TraceNotification trace} notification as being generated in response to
 * some action performed by a profile object on behalf of a profile.  For example,
 * if a profile object generates a traceable trace message using a
 * {@link javax.slee.facilities.Tracer Tracer} object, a trace notification will be
 * generated containing a <code>ProfileTableNotification</code> object that identifies
 * the profile table containing the profile.
 * @since SLEE 1.1
 */
public final class ProfileTableNotification extends AbstractNotificationSource implements NotificationSource {
    /**
     * The JMX notification type of alarm notifications that are generated in response
     * to a profile object interacting with the {@link javax.slee.facilities.AlarmFacility}.
     * <p>
     * The notification type is equal to the string "javax.slee.management.alarm.profiletable".
     */
    public static final String ALARM_NOTIFICATION_TYPE = "javax.slee.management.alarm.profiletable";

    /**
     * The JMX notification type of trace notifications that are generated in response
     * to a profile object interacting with a {@link javax.slee.facilities.Tracer} object.
     * <p>
     * The notification type is equal to the string "javax.slee.management.trace.profiletable".
     */
    public static final String TRACE_NOTIFICATION_TYPE = "javax.slee.management.trace.profiletable";

    /**
     * The JMX notification type of usage notifications that are generated by a
     * {@link javax.slee.usage.UsageMBean} containing a <code>ProfileTableNotification</code>
     * as a notification source.
     * <p>
     * The notification type is equal to the string "javax.slee.management.usage.profiletable".
     */
    public static final String USAGE_NOTIFICATION_TYPE = "javax.slee.management.usage.profiletable";

    /**
     * The JMX Object Name property key that identifies the name of the profile table
     * in a Usage MBean whose {@link javax.slee.usage.UsageMBean#NOTIFICATION_SOURCE_KEY}
     * property has a value equal to {@link #USAGE_NOTIFICATION_TYPE}.  This key is
     * equal to the string "profileTableName".
     * @see javax.slee.usage.UsageMBean#BASE_OBJECT_NAME
     * @see javax.slee.usage.UsageMBean#NOTIFICATION_SOURCE_KEY
     * @since SLEE 1.1
     */
    public static final String PROFILE_TABLE_NAME_KEY = "profileTableName";


    /**
     * Create a new <code>ProfileTableNotification</code> object that uniquely identifies a
     * profile table.
     * @param profileTableName the name of the profile table..
     * @throws NullPointerException if <code>profileTableName</code> is <code>null</code>.
     */
    public ProfileTableNotification(String profileTableName) {
        if (profileTableName == null) throw new NullPointerException("entityName is null");
        this.profileTableName = profileTableName;
    }

    /**
     * Get the name of the profile table of this notification source.
     * @return the name of the profile table.
     */
    public String getProfileTableName() {
        return profileTableName;
    }

    /**
     * Get the JMX notification type of alarm notifications generated in response
     * to a profile object interacting with the Alarm Facility.
     * @return the string defined by {@link #ALARM_NOTIFICATION_TYPE}.
     */
    public String getAlarmNotificationType() {
        return ALARM_NOTIFICATION_TYPE;
    }

    /**
     * Get the JMX notification type of trace notifications generated in response
     * to a profile object interacting with the Trace Facility.
     * @return the string defined by {@link #TRACE_NOTIFICATION_TYPE}.
     */
    public String getTraceNotificationType() {
        return TRACE_NOTIFICATION_TYPE;
    }

    /**
     * Get the JMX notification type of usage notifications generated in response
     * to a profile object interacting with its usage parameters.
     * @return the string defined by {@link #USAGE_NOTIFICATION_TYPE}.
     */
    public String getUsageNotificationType() {
        return USAGE_NOTIFICATION_TYPE;
    }

    /**
     * Compare this notification source for equality with another object.
     * @param obj the object to compare this with.
     * @return <code>true</code> if <code>obj</code> is an instance of this class and
     *        contains the same profile table name as this, <code>false</code> otherwise.
     */
    public boolean equals(Object obj) {
        if (obj == this) return true;
        if (!(obj instanceof ProfileTableNotification)) return false;

        return this.profileTableName.equals(((ProfileTableNotification)obj).profileTableName);
    }

    /**
     * Get a hash code value for this notification source.
     * @return a hash code value for this notification source.
     */
    public int hashCode() {
        return profileTableName.hashCode();
    }

    /**
     * Get a string representation for this notification source.
     * @return a string representation for this notification source.
     * @see Object#toString()
     */
    public String toString() {
        StringBuffer buf = new StringBuffer();
        buf.append("ProfileTableNotification[table=").append(profileTableName).append(']');
        return buf.toString();
    }

    /**
     * Compare this notification source with the specified object for order.
     * Returns a negative integer, zero, or a positive integer if this object
     * is less than, equal to, or greater than the specified object.
     * <p>
     * If <code>obj</code> is a <code>ProfileTableNotification</code>, order is
     * determined by comparing the encapsulated profile table name.  Otherwise, if
     * <code>obj</code> is a <code>NotificationSource</code>, ordering is determined
     * by comparing the class name of this class with the class name of <code>obj</code>.
     * @param obj the object to compare this with.
     * @return a negative integer, zero, or a positive integer if this notification
     *        source is considered less than, equal to, or greater than the
     *        specified object.
     * @throws ClassCastException if <code>obj</code> does not implement the
     *        {@link NotificationSource} interface.
     * @see Comparable#compareTo(Object)
     */
    public int compareTo(Object obj) {
        // can't compare with null
        if (obj == null) throw new NullPointerException("obj is null");
        if (obj == this) return 0;

        if (obj instanceof ProfileTableNotification) {
            // compare the profile table name
            ProfileTableNotification that = (ProfileTableNotification)obj;
            return this.profileTableName.compareTo(that.profileTableName);
        }
        else {
            return super.compareTo(TYPE, obj);
        }
    }


    // protected

    protected String getClassName() {
        return TYPE;
    }


    private final String profileTableName;

    // constant to avoid expensive getClass() invocations at runtime
    private static final String TYPE = ProfileTableNotification.class.getName();
}
